package com.itbaizhan.escase.service;

import com.itbaizhan.escase.document.News;
import com.itbaizhan.escase.repository.NewsRepository;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class NewService {
    //repository 定义的是搜索方法，不适合自动补全，所以自动补全要用ElasticsearchRestTemplate工具类
    @Autowired
    private ElasticsearchRestTemplate template;
    @Autowired
    private NewsRepository repository;
    //自动补齐  补齐的词语很多，把所有放进一个集合
    public List<String> autoSuggest(String keyword){
        //1,创建补齐请求
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        //2，构建补全条件
        CompletionSuggestionBuilder suggestionBuilder = SuggestBuilders
                .completionSuggestion("tags")   //补全的列名
                .prefix(keyword)
                .skipDuplicates(true)   //不重复
                .size(10);
        suggestBuilder.addSuggestion("prefix_suggestion",suggestionBuilder);
        //3,发送请求
        SearchResponse response = template.suggest(suggestBuilder, IndexCoordinates.of("news"));

        //4，处理结果   在elasticsearch中用高亮查询，suggest下都是一个个数组形式
        List<String> result = response
                .getSuggest()
                .getSuggestion("prefix_suggestion")
                .getEntries()
                //数组中的第一个
                .get(0)
                .getOptions()
                //用stream 把数组打印
                .stream()
                //注意导的包：org.elasticsearch.search.suggest.Suggest;
                .map(Suggest.Suggestion.Entry.Option::getText)
                .map(Text::toString)
                .collect(Collectors.toList());

            return result;
    }


    //查询关键字  高亮查询
    //查询所有内容（news的数据+高亮的数据），再创建集合，要把高亮字段替换原文的内容，放进集合里
    public List<News> highLightSearch(String keyword){
        //title与content 都是用同一个关键字
        List<SearchHit<News>> result = repository.findByTitleMatchesOrContentMatches(keyword,keyword);
        //处理结果，封装为news类型的集合
        List<News> newsList = new ArrayList<>();
        //SearchHit 里面的所有内容在content
        // 要把高亮字段替换原文的内容
        for(SearchHit<News> newsSearchHit:result){
            News news = newsSearchHit.getContent();

            //高亮字段
            Map<String,List<String>> highlightFields = newsSearchHit.getHighlightFields();
            if(highlightFields.get("title") != null){
                news.setTitle(highlightFields.get("title").get(0));
            }
            if(highlightFields.get("content") != null){
                news.setContent(highlightFields.get("content").get(0));
            }
            newsList.add(news);
        }
        return newsList;
    }
}